import { ref, createVNode, render, nextTick } from 'vue'

// 存储消息实例的容器
const messageContainer = ref(null)
const messages = ref([])
let currentPosition = 'rt' // 默认位置：右上角

// 位置配置映射
const positionStyles = {
  'rt': { // 右上角
    top: '20px',
    right: '20px',
    left: 'auto',
    alignItems: 'flex-end'
  },
  'rb': { // 右下角
    top: 'auto',
    right: '20px',
    bottom: '20px',
    left: 'auto',
    alignItems: 'flex-end'
  },
  'lt': { // 左上角
    top: '20px',
    right: 'auto',
    left: '20px',
    alignItems: 'flex-start'
  },
  'lb': { // 左下角
    top: 'auto',
    right: 'auto',
    bottom: '20px',
    left: '20px',
    alignItems: 'flex-start'
  }
}

// 创建消息容器
const createContainer = (position = 'rt') => {
  if (messageContainer.value) {
    // 如果位置改变，重新创建容器
    if (position !== currentPosition) {
      document.body.removeChild(messageContainer.value)
      messageContainer.value = null
    } else {
      return
    }
  }
  
  currentPosition = position
  const container = document.createElement('div')
  container.className = 'nuxt-message-container'
  
  // 应用位置样式
  const style = positionStyles[position] || positionStyles['rt']
  container.style.position = 'fixed'
  container.style.top = style.top
  container.style.right = style.right
  container.style.bottom = style.bottom
  container.style.left = style.left
  container.style.display = 'flex'
  container.style.flexDirection = 'column'
  container.style.alignItems = style.alignItems
  container.style.zIndex = '9999'
  
  document.body.appendChild(container)
  messageContainer.value = container
}

// 移除消息容器
const removeContainer = () => {
  if (messageContainer.value && messages.value.length === 0) {
    document.body.removeChild(messageContainer.value)
    messageContainer.value = null
    currentPosition = 'rt' // 重置位置
  }
}

// 消息组件
const MessageComponent = {
  props: {
    message: String,
    type: {
      type: String,
      default: 'info',
      validator: value => ['success', 'error', 'warning', 'info'].includes(value)
    },
    duration: {
      type: Number,
      default: 3000
    },
    width: {
      type: [String, Number],
      default: ''
    },
    onClose: Function
  },
  setup(props) {
    const visible = ref(true)
    
    // 关闭消息
    const close = () => {
      visible.value = false
      setTimeout(() => {
        props.onClose()
      }, 300) // 动画持续时间
    }
    
    // 设置自动关闭
    if (props.duration > 0) {
      setTimeout(close, props.duration)
    }
    
    return {
      visible,
      close
    }
  },
  render() {
    if (!this.visible) return null
    
    const iconMap = {
      success: '✓',
      error: '✗',
      warning: '!',
      info: 'i'
    }
    
    const bgColorMap = {
      success: 'bg-green-100 text-green-800',
      error: 'bg-red-100 text-red-800',
      warning: 'bg-yellow-100 text-yellow-800',
      info: 'bg-blue-100 text-blue-800'
    }
    
    // 处理宽度
    let widthStyle = ''
    if (this.width) {
      const widthValue = typeof this.width === 'number' ? `${this.width}px` : this.width
      widthStyle = `width: ${widthValue}; max-width: 90vw;`
    }
    
    return createVNode(
      'div',
      {
        class: `nuxt-message ${bgColorMap[this.type]} px-4 py-2 rounded shadow-lg flex items-start transition-all duration-300 transform opacity-0 translate-y-[-20px]`,
        style: `${widthStyle} margin-bottom: 10px; word-wrap: break-word; word-break: break-all;`,
        onVnodeMounted: () => {
          // 触发动画
          nextTick(() => {
            this.$el.classList.remove('opacity-0', 'translate-y-[-20px]')
          })
        }
      },
      [
        createVNode('span', { class: 'mr-2 font-bold pt-0.5' }, iconMap[this.type]),
        createVNode('span', { class: 'flex-1' }, this.message),
        createVNode(
          'button',
          {
            class: 'ml-4 text-gray-500 hover:text-gray-700 focus:outline-none',
            onClick: this.close
          },
          '×'
        )
      ]
    )
  }
}

// 主函数
const useMessage = () => {
  const createMessage = (message, options = {}) => {
    const { 
      type = 'info', 
      duration = 3000, 
      position = 'rt',
      width = ''
    } = typeof options === 'string' ? { type: options } : options
    
    createContainer(position)
    
    const messageId = Date.now().toString()
    const container = messageContainer.value
    
    // 创建消息实例
    const vnode = createVNode(MessageComponent, {
      message,
      type,
      duration,
      width,
      onClose: () => {
        // 从数组中移除消息
        messages.value = messages.value.filter(msg => msg.id !== messageId)
        
        // 如果没有消息了，移除容器
        removeContainer()
      }
    })
    
    // 创建临时DOM节点
    const tempDiv = document.createElement('div')
    render(vnode, tempDiv)
    
    // 添加到容器
    container.appendChild(vnode.el)
    
    // 保存消息引用
    messages.value.push({
      id: messageId,
      vnode
    })
    
    // 返回关闭函数
    return {
      close: () => {
        vnode.component.ctx.close()
      }
    }
  }

  const default_options = {
        position: 'rt',
        duration: 3000,
        width: '200px'
  }
  
  // 快捷方法
  const success = (message, options = {}) => {
    const opts = typeof options === 'string' ? { type: 'success', duration: parseInt(options) || 3000, width: '300px' } : { ...options, type: 'success' }
    const tmp_options = default_options
    Object.assign(tmp_options, opts)
    return createMessage(message, tmp_options)
  }
  
  const error = (message, options = {}) => {
    const opts = typeof options === 'string' ? { type: 'error', duration: parseInt(options) || 3000, width: '300px' } : { ...options, type: 'error' }
    const tmp_options = default_options
    Object.assign(tmp_options, opts)
    return createMessage(message, tmp_options)
  }
  
  const warning = (message, options = {}) => {
    const opts = typeof options === 'string' ? { type: 'warning', duration: parseInt(options) || 3000, width: '300px' } : { ...options, type: 'warning' }
    const tmp_options = default_options
    Object.assign(tmp_options, opts)
    return createMessage(message, tmp_options)
  }
  
  const info = (message, options = {}) => {
    const opts = typeof options === 'string' ? { type: 'info', duration: parseInt(options) || 3000, width: '300px' } : { ...options, type: 'info' }
    const tmp_options = default_options
    Object.assign(tmp_options, opts)
    return createMessage(message, tmp_options)
  }
  
  return {
    createMessage,
    success,
    error,
    warning,
    info
  }
}

const Message = useMessage()

export default () => {
    return {
        Message
    }
}